﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.ObjectMapping;
using Abp.Runtime.Caching;
using AutoMapper.QueryableExtensions;
using FwProject.Authorization.Users;
using FwProject.Core.Restaurant;
using FwProject.Core.SettlementInfoModel;
using FwProject.Distribution;
using FwProject.Distribution.Dto;
using FwProject.Manager;
using FwProject.Settlement.Dto;
using FwProject.PublicService.SqlExec;
using FwProject.Users;
using X.PagedList;
using FwProject.Restaurant;
using Abp.UI;
using FwProject.Core.Distribution;
using FwProject.PrePaymentInfo;
using Abp.AutoMapper;
using FwProject.Comm;
using Microsoft.EntityFrameworkCore;
using FwProject.BackGround.Settlement;
using Abp.BackgroundJobs;
using FwProject.BackGround;
using FwProject.Core.TypeNumber;
using Abp.RemoteEventBus;

namespace FwProject.Settlement
{
    /// <summary>
    /// 收据管理
    /// </summary>
    [AbpAuthorize]
    public class SettlementInfoAppService : FwProjectAppServiceBase, ISettlementInfoAppService
    {
        public readonly IRepository<SettlementInfo, Guid> _repositorySettlementInfo;
        public readonly IRepository<TypeNumberInfo, Guid> _repositoryTypeNumberInfos;
        public readonly IRepository<DistributionInfoDetails, Guid> _repositoryDistributionInfoDetails;
        public readonly IRepository<User, long> _repositoryUser;
        public readonly IRepository<RestaurantInfo, Guid> _repositoryRestaurantInfo;
        public readonly IRepository<PrePaymentInfoModel, Guid> _repositoryPrePaymentInfo;
        public readonly IRepository<ReceiptInfoModel, Guid> _repositoryReceiptInfo;
        public readonly IRepository<PaymentInfoModel, Guid> _repositoryPaymentInfoModel;

        public readonly IRepository<ReceiptInfoBySettlementModel, Guid> _repositoryReceiptInfoBySettlementModel;

        public readonly IDistributionAppService _idistributionAppService;
        public readonly IUserAppService _userAppService;
        private readonly SettlementInfoManager _settlementInfoManager;
        private readonly ISqlExecuter _sqlExecuter;
        public readonly ICacheManager _catchmanager;
        private readonly IRestaurantUserAppService _restaurantUserAppService;
        private readonly PrePaymentInfoAppService _prePaymentInfoAppService;

        private readonly IRepository<DistributionInfo, Guid> _repositoryDistributionInfo;

        private readonly IRepository<DriverLine, Guid> _repositoryLoadDriverLine;

        public IGuidGenerator _guid { get; set; }
        public IObjectMapper _map { get; set; }
        private readonly IBackgroundJobManager _backgroundJobManager;
        public SettlementInfoAppService(
            ICacheManager catchmanager, IRepository<User, long> repositoryUser,
            IRepository<SettlementInfo, Guid> repositorySettlementInfo,
            IRepository<RestaurantInfo, Guid> repositoryRestaurantInfo,
            IDistributionAppService idistributionAppService,
            IUserAppService userAppService, ISqlExecuter sqlExecuter,
            SettlementInfoManager settlementInfoManager,
            IRestaurantUserAppService restaurantUserAppService,
            IRepository<DistributionInfoDetails, Guid> repositoryDistributionInfoDetails,
            IRepository<DistributionInfo, Guid> repositoryDistributionInfo,
             PrePaymentInfoAppService prePaymentInfoAppService,
             IRepository<PrePaymentInfoModel, Guid> repositoryPrePaymentInfo,
             IRepository<ReceiptInfoModel, Guid> repositoryReceiptInfo,
             IRepository<PaymentInfoModel, Guid> repositoryPaymentInfoModel,
             IRepository<DriverLine, Guid> repositoryLoadDriverLine,
             IRepository<ReceiptInfoBySettlementModel, Guid> repositoryReceiptInfoBySettlementModel,
             IBackgroundJobManager backgroundJobManager,
              IRepository<TypeNumberInfo, Guid> repositoryTypeNumberInfos
             )
        {
            _repositoryTypeNumberInfos = repositoryTypeNumberInfos;
            _backgroundJobManager = backgroundJobManager;
            _prePaymentInfoAppService = prePaymentInfoAppService;
            _catchmanager = catchmanager;
            _repositoryUser = repositoryUser;
            _userAppService = userAppService;
            _repositorySettlementInfo = repositorySettlementInfo;
            _repositoryRestaurantInfo = repositoryRestaurantInfo;
            _idistributionAppService = idistributionAppService;
            _sqlExecuter = sqlExecuter;
            _settlementInfoManager = settlementInfoManager;
            _restaurantUserAppService = restaurantUserAppService;
            _repositoryDistributionInfoDetails = repositoryDistributionInfoDetails;
            _repositoryDistributionInfo = repositoryDistributionInfo;
            _repositoryPrePaymentInfo = repositoryPrePaymentInfo;
            _repositoryReceiptInfo = repositoryReceiptInfo;
            _repositoryPaymentInfoModel = repositoryPaymentInfoModel;
            _guid = SequentialGuidGenerator.Instance;
            _repositoryLoadDriverLine = repositoryLoadDriverLine;
            _repositoryReceiptInfoBySettlementModel = repositoryReceiptInfoBySettlementModel;
        }

        public IRemoteEventBus remoteEventBus { get; set; }//缓存对象
        public SettlementInfoAppService()
        {

            remoteEventBus = NullRemoteEventBus.Instance;
        }

        [Obsolete("过期不在使用UpdateDistributionStauts")]
        public async Task UpdateDistributionInfoStatus()
        {
            var catcheventDate = new RemoteEventData("Update")
            {
                Data = { ["model"] = "1" }
            };
            await remoteEventBus.PublishAsync("SystemDistributionInfoStatus", catcheventDate);
        }



        /// <summary>
        /// 创建一条收据
        /// </summary>
        /// <returns>The create.</returns>
        /// <param name="input">Input.</param>
        public async Task<Guid> Create(SettlementInfoInput input)
        {

            var user = await base.GetCurrentUserAsync();
            var model = _map.Map<SettlementInfo>(input);
            model.Id = _guid.Create();
            model.FactoryinfoId = user.FactoryinfoId;
            await _repositorySettlementInfo.InsertAndGetIdAsync(model);
            foreach (var item in input.Distribution)
            {
                ///同时修改该结账下的所有配送表结构
                await _idistributionAppService.SetUpdateOrder(item, model.Id);
            }
            return model.Id;
        }
        /// <summary>
        /// 收据审核
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task Check(Guid id, SettlementInfoInput input)
        {
            var model = await _repositorySettlementInfo.GetAsync(id);
            model.ExamineStatus = Core.SettlementInfoModel.ExamineStatus.已审核;
            model.Discountprice = input.ReceivedDiscount;
            model.Actualprice = model.Totalprice - input.ReceivedDiscount;
            model.EmployeeDriverid = input.EmployeeDriverid;
            model.RemarksConten = input.RemarksConten;
            await _repositorySettlementInfo.UpdateAsync(model);
        }
        /// <summary>
        /// 收据反审核如果被收款单引用就不能修改
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task AntiCheck(Guid id)
        {
            var model = await _repositorySettlementInfo.GetAsync(id);
            var rBy = _repositoryReceiptInfoBySettlementModel.GetAll().Where(o => o.SettlementId == model.Id && o.ToVoidStatus == ToVoidStatus.未作废).FirstOrDefault();
            if (rBy != null)
            {
                //var receipt = _repositoryReceiptInfo.GetAll().Where(o => o.Id == model.ReceiptInfoId.Value).FirstOrDefault();
                //if (receipt.PaymentState == PaymentState.已缴款)
                throw new UserFriendlyException("该结账信息已被收款单引用,数据已锁定无法更改");
            }
            model.ExamineStatus = Core.SettlementInfoModel.ExamineStatus.已退回;
            model.RestaurantPayStatus = RestaurantPayStatus.未收款;
            await _repositorySettlementInfo.UpdateAsync(model);
        }
        /// <summary>
        /// 删除单据
        /// </summary>
        /// <returns></returns>
        public async Task DeleteSettlement(Guid[] ids)
        {
            foreach (var id in ids)
            {
                var model = await _repositorySettlementInfo.GetAsync(id);
                if (model.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核)
                    throw new UserFriendlyException(200, "不能删除已审核的单据！");
            }
            foreach (var id in ids)
            {
                var model = await _repositorySettlementInfo.GetAsync(id);
                var rBy = _repositoryReceiptInfoBySettlementModel.GetAll().Where(o => o.SettlementId == model.Id && o.ToVoidStatus == ToVoidStatus.未作废).FirstOrDefault();
                if (rBy != null)
                    throw new UserFriendlyException($"单据号{model.CreationNumber}已被收款单引用不可删除!");

                model.RestaurantPayStatus = RestaurantPayStatus.作废;
                var distribution = _repositoryDistributionInfo.GetAllIncluding(o => o.DistributionInfoListDetails).Where(o => o.SettlementId == id);
                foreach (var item in distribution)
                {
                    item.SettlementId = null;
                    item.Pricestatus = Pricestatus.制单退回;
                    foreach (var d in item.DistributionInfoListDetails)
                    {
                        d.PricesId = Guid.Empty;
                        d.Pricestatus = Pricestatus.制单退回;
                    }
                }
            }
        }

        #region 获取一个收据对象
        /// <summary>
        /// 获取一条结账信息
        /// </summary>
        /// <returns>The by identifier async.</returns>
        /// <param name="id">Identifier.</param>
        public SettlementInfoDto GetById(Guid id)
        {
            var model = _repositorySettlementInfo.GetAllIncluding(o => o.RestaurantInfoModel, o => o.EmployeeDriverDao).Where(o => o.Id == id).FirstOrDefault();
            return _map.Map<SettlementInfoDto>(model);
        }

        #endregion
        /// <summary>
        /// 获取收据集合(打印配送明细)
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public List<SettlementInfoPrintDto> GetListById(List<Guid> ids)
        {

            //var m = _repositoryDistributionInfoDetails.GetAll().Where(o => o.PricesId != Guid.Empty).GroupBy(g => new { g.PricesId, g.TypeNumberInfoId, g.TypeNumberPrice, g.TypeNumberName }).Join(_repositoryTypeNumberInfos.GetAll(), s => s.Key.TypeNumberInfoId, n => n.Id, (s, n) => new DistributionDetailsPrintDto
            //{
            //    PricesId = s.Key.PricesId,
            //    TypeNumberName = s.Key.TypeNumberName,
            //    TypeNumberPrice = s.Key.TypeNumberPrice,
            //    DistributionBoxCount = s.Sum(y => y.Distributioncount),
            //    DistributionCount = s.Sum(y => y.Distributioncount * n.Count),
            //    RecoveryCount = s.Sum(y => y.Recoverycount * n.Count),
            //    RecoveryBoxCount = s.Sum(y => y.Recoverycount),
            //    BackBoxCount = s.Sum(y => y.Backboxcount),
            //    BackCount = s.Sum(y => y.Backnumbercount),
            //    ExchangeBoxCount = s.Sum(y => y.Exchangegoodscount),
            //    GiveBoxCount = s.Sum(y => y.Givecount),
            //    DamageCount = s.Sum(y => y.Damagecount),
            //    SumPrice = s.Sum(y => y.Sumprice)
            //});

            var m = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.TypeNumberInfoModel).Where(o => o.PricesId != Guid.Empty);
            List<DistributionDetailsPrintDto> d = new List<DistributionDetailsPrintDto>();
            foreach (var item in m)
            {
                DistributionDetailsPrintDto dto = new DistributionDetailsPrintDto();
                dto.DistributionDate = item.CreationTime;
                dto.DistributionBoxCount = item.Distributioncount;
                dto.DistributionCount = item.Distributioncount * item.TypeNumberInfoModel.Count;
                dto.RecoveryBoxCount = item.Recoverycount;
                dto.RecoveryCount = item.Recoverycount * item.TypeNumberInfoModel.Count;
                dto.BackBoxCount = item.Backboxcount;
                dto.BackCount = item.Backnumbercount;
                dto.GiveBoxCount = item.Givecount;
                dto.ExchangeBoxCount = item.Exchangegoodscount;
                dto.DamageCount = item.Damagecount;
                dto.PricesId = item.PricesId;
                dto.SumPrice = item.Sumprice;
                dto.TypeNumberName = item.TypeNumberName;
                dto.TypeNumberPrice = item.TypeNumberPrice;
                d.Add(dto);
            }

            var list = _repositorySettlementInfo.GetAllIncluding(o => o.RestaurantInfoModel, o => o.EmployeeDriverDao).Where(o => ids.Any(a => o.Id == a))
                  .GroupJoin(d,
                   i => i.Id, n => n.PricesId, (i, n) => new SettlementInfoPrintDto
                   {
                       RestaurantInfoModel = i.RestaurantInfoModel.MapTo<RestaurantInfoModel>(),
                       EmployeeDriverDao = i.EmployeeDriverDao.MapTo<UserModel>(),
                       Discountprice = i.Discountprice + i.ReceivedDiscount,
                       RemarksConten = i.RemarksConten,
                       CreationNumber = i.CreationNumber,
                       CreationTime = i.CreationTime,
                       DeliveryDate = i.DeliveryDate,
                       Totalprice = i.Totalprice,
                       MonthBegin = i.BeginTime.Value.Month,
                       MonthEnd = i.EndTime.Value.Month,
                       Stock = i.RestaurantInfoModel.Stock + n.Sum(o => o.DistributionBoxCount) + n.Sum(o => o.GiveBoxCount) - n.Sum(o => o.RecoveryBoxCount),
                       TypeNumber = n.ToList(),
                   });

            return list.ToList();

        }

        #region 收款单详情收据列表
        /// <summary>
        /// 根据收款编号获取收据信息
        /// </summary>
        /// <param name="receiptInfoId"></param>
        /// <returns></returns>
        public async Task<List<SettlementInfoDto>> GetSettlementInfoByReceiptInfoIdAsync(Guid receiptInfoId)
        {


            var list = _repositoryReceiptInfoBySettlementModel.GetAll().Where(o => o.ReceiptInfoId == receiptInfoId && o.ToVoidStatus == ToVoidStatus.未作废).Join(_repositorySettlementInfo.GetAll(), i => i.SettlementId, n => n.Id, (i, b) => new
            {
                Id = b.Id,
                ToVoidStatus = i.ToVoidStatus,
                Actualprice = b.Actualprice/* - list.Where(o => o.SettlementId == b.Id && o.ReceiptInfoId != receiptInfoId && o.ToVoidStatus == ToVoidStatus.未作废).Sum(o => o.UsePrePayment + o.PreferentialAmount + o.TaskBackAmount)*/,
                ReceivedPrice = i.TaskBackAmount,
                ReceivedDiscount = i.PreferentialAmount,
                UsePrePayment = i.UsePrePayment,
                CreationNumber = b.CreationNumber,
                DeliveryDate = b.DeliveryDate,
                Totalprice = b.Actualprice,
                BalanceWayEnum = b.BalanceWayEnum,
                RestaurantPayStatus = b.RestaurantPayStatus,
                CreationTime = b.CreationTime,
                RemarksConten = b.RemarksConten

            });

            var query = list.GroupJoin(_repositoryReceiptInfoBySettlementModel.GetAll().Where(o => o.ReceiptInfoId != receiptInfoId && o.ToVoidStatus == ToVoidStatus.未作废), i => i.Id, j => j.SettlementId, (i, j) => new SettlementInfoDto
            {
                Id = i.Id,
                ToVoidStatus = i.ToVoidStatus,
                Actualprice = i.Actualprice - j.Sum(o => o.UsePrePayment + o.PreferentialAmount + o.TaskBackAmount),
                ReceivedPrice = i.ReceivedPrice,
                ReceivedDiscount = i.ReceivedDiscount,
                UsePrePayment = i.UsePrePayment,
                CreationNumber = i.CreationNumber,
                DeliveryDate = i.DeliveryDate,
                Totalprice = i.Actualprice,
                BalanceWayEnum = i.BalanceWayEnum,
                RestaurantPayStatus = i.RestaurantPayStatus,
                CreationTime = i.CreationTime,
                RemarksConten = i.RemarksConten
            });

            return await query.ToListAsync();

        }
        #endregion

        /// <summary>
        /// 根据餐厅Id获取收据信息
        /// </summary>
        /// <param name="restaurantId">餐厅Id</param>
        /// <returns></returns>
        public async Task<List<SettlementInfoDto>> GetSettlementInfoByRestaurantIdAsync(Guid restaurantId)
        {
            var query = (await GetCache).AsQueryable().Where(o => o.Restaurantid == restaurantId && (o.RestaurantPayStatus == RestaurantPayStatus.未收款 || o.RestaurantPayStatus == RestaurantPayStatus.部分收款) && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核);

            return query.MapTo<List<SettlementInfoDto>>();
        }

        #region App餐厅查看自己的收据情况
        /// <summary>
        /// 返回已结账信息列表
        /// </summary>
        /// <returns>The restaurant paged list async.</returns>
        /// <param name="结账编号">Page index.</param>
        public async Task<IPagedList<SettlementAppToBInfoDto>> GetPagedListAsync(int pageIdx, int pageSize, RestaurantPayStatus? restaurantPayStatus, Guid? Restaurant, DateTime? begin, DateTime? end)
        {
            var user = await base.GetCurrentUserAsync();

            var query = (await GetCache).AsQueryable();
            query = query.Where(o => o.FactoryinfoId == user.FactoryinfoId && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核);

            if (restaurantPayStatus.HasValue && restaurantPayStatus == RestaurantPayStatus.未收款)
                query = query.Where(o => o.RestaurantPayStatus == restaurantPayStatus);

            if (restaurantPayStatus.HasValue && restaurantPayStatus != RestaurantPayStatus.未收款)
                query = query.Where(o => o.RestaurantPayStatus == RestaurantPayStatus.部分收款 || o.RestaurantPayStatus == RestaurantPayStatus.已收完款);


            if (Restaurant != null)
                query = query.Where(o => o.Restaurantid == Restaurant);

            if (begin != null)
                query = query.Where(o => o.CreationTime >= begin);
            if (end != null)
                query = query.Where(o => o.CreationTime <= end.Value.AddHours(24));

            var list = query.GroupJoin(_repositoryDistributionInfoDetails.GetAllIncluding(o => o.TypeNumberInfoModel).GroupBy(t => new
            {
                t.Restaurantid,
                t.TypeNumberInfoId,
                t.PricesId,
                t.TypeNumberName
            }).Select(m => new DistributionByTypeNumber
            {
                SettlementId = m.Key.PricesId,
                Distributioncount = m.Sum(s => s.Distributioncount),
                Backboxcount = m.Sum(s => s.Backboxcount),
                Backnumbercount = m.Sum(s => s.Backnumbercount),
                Damagecount = m.Sum(s => s.Damagecount),
                Exchangegoodscount = m.Sum(s => s.Exchangegoodscount),
                Recoverycount = m.Sum(s => s.Recoverycount),
                Givecount = m.Sum(s => s.Givecount),
                TypeNumberName = m.Key.TypeNumberName,
                Restaurantid = m.Key.Restaurantid

            }), i => i.Id, k => k.SettlementId, (i, k) => new SettlementAppToBInfoDto
            {
                Id = i.Id,
                Restaurantid = i.Restaurantid.Value,
                RestaurantInfoModel = _map.Map<RestaurantInfoModel>(i.RestaurantInfoModel),
                CreationNumber = i.CreationNumber,
                Totalprice = i.Totalprice,
                Discountprice = i.Discountprice,
                Actualprice = i.Actualprice,
                ReceivedPrice = i.ReceivedPrice,
                ReceivedDiscount = i.ReceivedDiscount,
                UsePrePayment = i.UsePrePayment,
                RestaurantPayStatus = i.RestaurantPayStatus,
                EmployeeDriverid = i.EmployeeDriverid,
                EmployeeDriverDao = _map.Map<UserModel>(i.EmployeeDriverDao),
                BalanceWayEnum = i.BalanceWayEnum,
                RemarksConten = i.RemarksConten,
                CreatorUserId = i.CreatorUserId,
                CreationTime = i.CreationTime,
                DeliveryDate = i.DeliveryDate,
                DistributionByTypeNumber = k.AsQueryable()
            });
            return await list.OrderByDescending(m => m.CreationTime).ToPagedListAsync(pageIdx, pageSize);
        }
        #endregion
        #region App收款人查看自己的未收款的收据情况
        public async Task<IPagedList<SettlementInfoDto>> GetPayeeSelfListAsync(int pageIdx, int pageSize, string Restaurantname, DateTime? begin, DateTime? end)
        {
            var user = await base.GetCurrentUserAsync();

            var query = (await GetCache).AsQueryable();
            query = query.Where(o => o.FactoryinfoId == user.FactoryinfoId && (o.RestaurantPayStatus == RestaurantPayStatus.部分收款 || o.RestaurantPayStatus == RestaurantPayStatus.未收款) && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核 && o.EmployeeDriverid == AbpSession.UserId.Value && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核);

            if (!string.IsNullOrEmpty(Restaurantname))
                query = query.Where(o => o.RestaurantInfoModel.RestaurantName.Contains(Restaurantname));

            if (begin != null)
                query = query.Where(o => o.CreationTime >= begin);
            if (end != null)
                query = query.Where(o => o.CreationTime <= end.Value.AddHours(24));

            return await query.OrderByDescending(m => m.CreationTime).ProjectTo<SettlementInfoDto>().ToPagedListAsync(pageIdx, pageSize);
        }
        #endregion
        #region App收款人查看自己的已收款的收据情况
        public async Task<IPagedList<SettlementInfoDto>> GetPayeeSelfEnterPayListAsync(int pageIdx, int pageSize, string Restaurantname, DateTime? begin, DateTime? end)
        {
            var user = await base.GetCurrentUserAsync();

            var query = (await GetCache).AsQueryable();
            query = query.Where(o => o.FactoryinfoId == user.FactoryinfoId && (o.RestaurantPayStatus == RestaurantPayStatus.部分收款 || o.RestaurantPayStatus == RestaurantPayStatus.已收完款) && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核 && o.EmployeeDriverid == AbpSession.UserId.Value && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核);

            if (!string.IsNullOrEmpty(Restaurantname))
                query = query.Where(o => o.RestaurantInfoModel.RestaurantName.Contains(Restaurantname));

            if (begin != null)
                query = query.Where(o => o.CreationTime >= begin);
            if (end != null)
                query = query.Where(o => o.CreationTime <= end.Value.AddHours(24));


            return await query.OrderByDescending(m => m.CreationTime).ProjectTo<SettlementInfoDto>().ToPagedListAsync(pageIdx, pageSize);
        }
        #endregion
        #region App查看该餐厅的所有未收款情况
        /// <summary>
        /// App司机端返回分配给司机的收款
        /// </summary>
        /// <param name="RestaurantId"></param>
        /// <returns>Item1 总的应收，Item2 预收金额</returns>
        public async Task<Tuple<decimal, decimal>> GetAllSettlementPrice(Guid RestaurantId)
        {
            var sumPrice = _repositorySettlementInfo.GetAll().Where(o => o.Restaurantid == RestaurantId && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核 && (o.RestaurantPayStatus == RestaurantPayStatus.未收款 || o.RestaurantPayStatus == RestaurantPayStatus.已收完款) && o.EmployeeDriverid == AbpSession.UserId.Value).Sum(o => o.Actualprice - o.ReceivedPrice - o.ReceivedDiscount - o.UsePrePayment);
            var paymentPrice = await _prePaymentInfoAppService.GetRestaurantInfoNamePrePayment(RestaurantId);
            return Tuple.Create<decimal, decimal>(sumPrice, paymentPrice);
        }


        #endregion

        /// <summary>
        /// 获取快速收款列表
        /// </summary>
        /// <param name="pageIdx"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<IPagedList<ReceiptFastlyDto>> GetReceiptFastlyListAsync(int pageIdx, int pageSize, string restaurantName, BalanceWayEnum? balanceWay, BalanceCycleEnum? balanceCycle, Guid? Line, long? DriverId)
        {
            var user = await base.GetCurrentUserAsync();
            ///查看剩余金额是否收完
            var model = (await GetCache).AsQueryable().Where(o => o.FactoryinfoId == user.FactoryinfoId && (o.Actualprice - o.UsePrePayment - o.ReceivedDiscount) != o.ReceivedPrice && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核 && (o.RestaurantPayStatus == RestaurantPayStatus.未收款 || o.RestaurantPayStatus == RestaurantPayStatus.部分收款));

            if (DriverId.HasValue)
            {
                //获取司机负责的餐厅
                var restaurants = _repositoryRestaurantInfo.GetAll().Where(o => o.EmployeeDriverid == DriverId.Value).Select(o => o.Id);
                //过滤收款
                model = model.Where(o => restaurants.Any(s => s == o.Restaurantid));
            }
            else if (Line.HasValue)
            {
                //获取线路上的配送司机
                var drivers = _repositoryLoadDriverLine.GetAll().Where(o => o.LineId == Line.Value).Select(o => o.DriverId);
                //获取司机负责的餐厅
                var restaurants = _repositoryRestaurantInfo.GetAll().Where(o => drivers.Any(s => s == o.EmployeeDriverid)).Select(o => o.Id);

                model = model.Where(o => restaurants.Any(s => s == o.Restaurantid));
            }

            var data = model.GroupBy(o => new { o.Restaurantid, o.RestaurantInfoModel.RestaurantName, o.RestaurantInfoModel.BalanceCycle, o.RestaurantInfoModel.BalanceWay }).Select(a => new
            {
                RestaurantId = a.Key.Restaurantid,
                a.Key.RestaurantName,
                a.Key.BalanceCycle,
                a.Key.BalanceWay,
                TotalPrice = a.Sum(b => b.Actualprice - b.ReceivedDiscount - b.ReceivedPrice - b.UsePrePayment)
            });

            var data2 = data.GroupJoin(_repositoryPrePaymentInfo.GetAll().Where(o => o.PrePaymentInfoStatus == PrePaymentInfoStatus.已审核), a => a.RestaurantId, b => b.RestaurantInfoId, (a, b) => new ReceiptFastlyDto
            {
                RestaurantId = a.RestaurantId.Value,
                RestaurantName = a.RestaurantName,
                BalanceWay = a.BalanceWay,
                BalanceCycle = a.BalanceCycle,
                TotalPrice = a.TotalPrice,
                PrePaymentBalance = b.Where(o => o.PrePaymentInfoType == PrePaymentInfoType.收预交金).Sum(o => o.PrePaymentPrice) - b.Where(o => o.PrePaymentInfoType == PrePaymentInfoType.退预交金).Sum(o => o.PrePaymentPrice)
            }).GroupJoin(_repositoryReceiptInfo.GetAll().Where(o => o.FactoryinfoId == user.FactoryinfoId && o.ToVoid == ToVoidStatus.未作废).GroupBy(g => g.RestaurantId).Select(s => new { RestaurantId = s.Key, UsePrePayment = s.Sum(sum => sum.UsePrePayment) }),
            i => i.RestaurantId, b => b.RestaurantId, (i, b) => new ReceiptFastlyDto
            {
                RestaurantId = i.RestaurantId,
                RestaurantName = i.RestaurantName,
                BalanceWay = i.BalanceWay,
                BalanceCycle = i.BalanceCycle,
                TotalPrice = i.TotalPrice,
                PrePaymentBalance = i.PrePaymentBalance - b.Sum(s => s.UsePrePayment)
            });

            if (!string.IsNullOrEmpty(restaurantName))
                data2 = data2.Where(o => o.RestaurantName.Contains(restaurantName));
            if (balanceWay.HasValue)
                data2 = data2.Where(o => o.BalanceWay == balanceWay.Value);
            if (balanceCycle.HasValue)
                data2 = data2.Where(o => o.BalanceCycle == balanceCycle.Value);

            return await data2.ToPagedListAsync(pageIdx, pageSize);
        }
        /// <summary>
        /// 获取应收明细列表
        /// </summary>
        /// <returns></returns>

        public async Task<IPagedList<SettlementInfoDto>> GetReceivableDetailsAsync(int pageIdx, int pageSize, Guid id, DateTime? beginTime, DateTime? endTime)
        {
            var model = _repositorySettlementInfo.GetAll().Where(o => o.Restaurantid == id && (o.RestaurantPayStatus == RestaurantPayStatus.未收款 || o.RestaurantPayStatus == RestaurantPayStatus.部分收款));
            if (beginTime.HasValue)
                model = model.Where(o => o.CreationTime >= beginTime);
            if (endTime.HasValue)
                model = model.Where(o => o.CreationTime <= endTime.Value.AddHours(24));

            return await model.ProjectTo<SettlementInfoDto>().ToPagedListAsync(pageIdx, pageSize);
        }

        /// <summary>
        /// 查询收款单
        /// </summary>
        /// <param name="pageIdx"></param>
        /// <param name="pageSize"></param>
        /// <param name="Restaurant"></param>
        /// <param name="begin"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public async Task<IPagedList<SettlementReceivableDto>> GetReceivablePagedListAsync(int pageIdx, int pageSize, DateTime? beginTime, DateTime? endTime, DateTime? beginDate, DateTime? endDate, string restaurantName, long? driverId, Core.SettlementInfoModel.ExamineStatus? ExamineStatus, RestaurantPayStatus? restaurantPayStatus, Guid? Line)
        {
            #region Bygone
            //var where1 = "";
            //var where2 = "";
            //if (beginTime.HasValue)
            //{
            //    where1 = "and a.CreationTime >='" + beginTime.Value + "'";
            //}

            //if (endTime.HasValue)
            //{
            //    endTime = endTime.Value.AddHours(24);
            //    where2 = " and a.CreationTime<='" + endTime.Value + "'";
            //}

            //var usermodel = await _userAppService.GetByIdUserAsync(AbpSession.UserId.Value);
            //string sql = $@"select a.Id as SettlementId,a.ExamineStatus,RestaurantPayStatus,a.CreationTime,CreationNumber,d.Id as DriverId,Name as DriverName,RestaurantName,a.TotalPrice,Discountprice,Actualprice 
            //                from SettlementInfo a,RestaurantInfo b,AbpUsers d where a.Restaurantid = b.id  and b.EmployeeDriverid=d.Id and b.FactoryinfoId='{usermodel.FactoryinfoId}' {where1} {where2} order by a.CreationTime desc";

            //var model = _sqlExecuter.FromDapperSqlQuery<SettlementReceivableDto>(sql, null).AsQueryable();
            //if (!string.IsNullOrEmpty(restaurantName))
            //    model = model.Where(o => o.RestaurantName.Contains(restaurantName));

            //if (!string.IsNullOrEmpty(driverId))
            //    model = model.Where(o => o.DriverId.ToString() == driverId);

            //return await model.ToPagedListAsync(pageIdx, pageSize);
            #endregion

            var user = await base.GetCurrentUserAsync();
            var query = _repositorySettlementInfo.GetAll().Where(O => O.FactoryinfoId == user.FactoryinfoId).GroupJoin(_repositoryReceiptInfoBySettlementModel.GetAll().Where(o => o.FactoryinfoId == user.FactoryinfoId && o.ToVoidStatus == ToVoidStatus.未作废), i => i.Id, j => j.SettlementId, (i, j) => new
            {
                i.Id,
                i.ExamineStatus,
                i.RestaurantPayStatus,
                i.CreationTime,
                i.CreationNumber,
                i.EmployeeDriverid,
                i.DeliveryDate,
                i.Restaurantid,
                i.Totalprice,
                i.ReceivedDiscount,
                i.Discountprice,
                i.Actualprice,
                i.UsePrePayment,
                i.BeginTime,
                i.EndTime,
                Already = j.Sum(o => o.TaskBackAmount + o.UsePrePayment + o.PreferentialAmount)
            });

            var query2 = query.Join(_repositoryRestaurantInfo.GetAll().Where(o => o.BalanceWay == BalanceWayEnum.定期结算), i => i.Restaurantid, j => j.Id, (i, j) => new SettlementReceivableDto
            {
                SettlementId = i.Id,
                ExamineStatus = i.ExamineStatus,
                RestaurantPayStatus = i.RestaurantPayStatus,
                CreationTime = i.CreationTime,
                CreationNumber = i.CreationNumber,
                DriverId = i.EmployeeDriverid,
                DeliveryDate = i.DeliveryDate,
                RestaurantName = j.RestaurantName,
                TotalPrice = i.Totalprice,
                ReceivedDiscount = i.ReceivedDiscount,
                Discountprice = i.Discountprice,
                Actualprice = i.Actualprice,
                UsePrePayment = i.UsePrePayment,
                UncollectedPrice = i.Actualprice - i.Already,
                BeginTime = i.BeginTime.Value,
                EndTime = i.EndTime.Value
            });

            if (beginTime.HasValue)
                query2 = query2.Where(o => o.CreationTime >= beginTime.Value);


            if (endTime.HasValue)
                query2 = query2.Where(o => o.CreationTime <= endTime.Value.AddHours(24));

            if (beginDate.HasValue && endDate.HasValue)
            {
                query2 = query2.Where(o => o.BeginTime >= beginDate.Value && o.EndTime <= endDate.Value);
            }

            if (!string.IsNullOrEmpty(restaurantName))
                query2 = query2.Where(o => o.RestaurantName.Contains(restaurantName));

            if (driverId.HasValue)//司机Id
                query2 = query2.Where(o => o.DriverId == driverId);

            if (ExamineStatus.HasValue)//财务审核状态
                query2 = query2.Where(o => o.ExamineStatus == ExamineStatus.Value);

            if (restaurantPayStatus.HasValue)//收款审核状态
                query2 = query2.Where(o => o.RestaurantPayStatus == restaurantPayStatus.Value);

            if (Line.HasValue && Line != Guid.Empty)//线路Id
            {
                var lineUsers = _repositoryLoadDriverLine.GetAll().Where(o => o.LineId == Line.Value).Select(o => o.DriverId);
                query2 = query2.Where(o => lineUsers.Any(s => s == o.DriverId));
            }

            return await query2.Where(o => o.RestaurantPayStatus != RestaurantPayStatus.作废).OrderBy(o => o.ExamineStatus).ThenByDescending(o => o.CreationTime).ToPagedListAsync(pageIdx, pageSize);

        }
        /// <summary>
        /// 收据查询导出
        /// </summary>
        /// <returns></returns>
        public async Task<List<SettlementReceivableDto>> GetExportReceivableListAsync(DateTime? beginTime, DateTime? endTime, string restaurantName, long? driverId, Core.SettlementInfoModel.ExamineStatus? ExamineStatus, RestaurantPayStatus? restaurantPayStatus, Guid? Line)
        {
            var user = await base.GetCurrentUserAsync();
            var query = _repositorySettlementInfo.GetAllIncluding(o => o.RestaurantInfoModel, o => o.EmployeeDriverDao).Where(O => O.FactoryinfoId == user.FactoryinfoId && O.RestaurantInfoModel.BalanceWay == BalanceWayEnum.定期结算).GroupJoin(_repositoryReceiptInfo.GetAll().Where(o => o.FactoryinfoId == user.FactoryinfoId && o.ToVoid == ToVoidStatus.未作废), i => i.ReceiptInfoId, j => j.Id, (i, j) => new
            {
                i.Id,
                i.ExamineStatus,
                i.RestaurantPayStatus,
                i.CreationTime,
                i.CreationNumber,
                i.EmployeeDriverid,
                i.DeliveryDate,
                DriverName = i.EmployeeDriverDao == null ? "" : i.EmployeeDriverDao.Name,
                i.RestaurantInfoModel.RestaurantName,
                i.Totalprice,
                i.ReceivedDiscount,
                i.Discountprice,
                i.Actualprice,
                i.UsePrePayment,
                Already = j.Sum(o => o.TaskBackAmount)

            }).Select(o => new SettlementReceivableDto
            {
                SettlementId = o.Id,
                ExamineStatus = o.ExamineStatus,
                RestaurantPayStatus = o.RestaurantPayStatus,
                CreationTime = o.CreationTime,
                CreationNumber = o.CreationNumber,
                DriverId = o.EmployeeDriverid,
                DeliveryDate = o.DeliveryDate,
                DriverName = o.DriverName,
                RestaurantName = o.RestaurantName,
                TotalPrice = o.Totalprice,
                ReceivedDiscount = o.ReceivedDiscount,
                Discountprice = o.Discountprice,
                Actualprice = o.Actualprice,
                UsePrePayment = o.UsePrePayment,
                UncollectedPrice = o.Actualprice - o.Already
            });

            if (beginTime.HasValue)
                query = query.Where(o => o.CreationTime >= beginTime.Value);


            if (endTime.HasValue)
                query = query.Where(o => o.CreationTime <= endTime.Value.AddHours(24));


            if (!string.IsNullOrEmpty(restaurantName))
                query = query.Where(o => o.RestaurantName.Contains(restaurantName));

            if (driverId.HasValue)//司机Id
                query = query.Where(o => o.DriverId == driverId);

            if (ExamineStatus.HasValue)//财务审核状态
                query = query.Where(o => o.ExamineStatus == ExamineStatus.Value);

            if (restaurantPayStatus.HasValue)//收款审核状态
                query = query.Where(o => o.RestaurantPayStatus == restaurantPayStatus.Value);

            if (Line.HasValue && Line != Guid.Empty)//线路Id
            {
                var lineUsers = _repositoryLoadDriverLine.GetAll().Where(o => o.LineId == Line.Value).Select(o => o.DriverId);
                query = query.Where(o => lineUsers.Any(s => s == o.DriverId));
            }

            return await query.Where(o => o.RestaurantPayStatus != RestaurantPayStatus.作废).OrderBy(o => o.ExamineStatus).ThenByDescending(o => o.CreationTime).ToListAsync();
        }

        public async Task<IPagedList<SettlementInfoEnterDto>> GetRestaurantNotPayEnterPagedListAsync(int page, int pageSize, DateTime? beginTime, DateTime? endTime)
        {

            var user = await GetCurrentUserAsync();
            var model = await _restaurantUserAppService.GetByUserRestaurant(user.Id);
            if (model == null)
                throw new UserFriendlyException("当前用户没有绑定餐厅信息");

            try
            {
                var query = (await GetCache).AsQueryable().Where(o => (o.RestaurantPayStatus == RestaurantPayStatus.未收款 || o.RestaurantPayStatus == RestaurantPayStatus.部分收款) && o.RestaurantInfoModel.FactoryinfoId == user.FactoryinfoId && o.Restaurantid == model.RestaurantInfoId);

                if (beginTime != null)
                    query = query.Where(o => o.CreationTime >= beginTime);
                if (endTime != null)
                    query = query.Where(o => o.CreationTime <= endTime.Value.AddHours(24));


                return await query.OrderByDescending(m => m.CreationTime).ProjectTo<SettlementInfoEnterDto>().ToPagedListAsync(page, pageSize);
            }
            catch (Exception exe)
            {
                throw new UserFriendlyException("当前用户没有绑定餐厅信息");
            }

        }

        #region 后台查看缴款

        public async Task<IPagedList<SettlementInfoPrePaymentInfo>> GetAllPaymentInfo(int page, int pageSize, long? id)
        {
            var user = await base.GetCurrentUserAsync();

            var data = _repositorySettlementInfo.GetAll().Where(o => o.FactoryinfoId == user.FactoryinfoId && o.EmployeeDriverid.HasValue == true);
            if (id.HasValue)
                data = data.Where(o => o.EmployeeDriverid == id);

            var userList = data.GroupBy(g => g.EmployeeDriverid).Select(s => new { UserId = s.Key }).ToArray();

            ///得到收据的收款信息同时查看没有缴款的收据
            var m = _repositoryReceiptInfoBySettlementModel.GetAll().Where(o => o.ToVoidStatus != ToVoidStatus.已作废).Join(_repositoryReceiptInfo.GetAll().Where(o => o.PaymentState == PaymentState.未缴款), i => i.ReceiptInfoId, n => n.Id, (i, n) => new
            {
                i.SettlementId,
                Actualprice = i.TaskBackAmount + i.PreferentialAmount + i.UsePrePayment
            }).Join(_repositorySettlementInfo.GetAll(), i => i.SettlementId, n => n.Id, (i, n) => new
            {
                n.ReceiptInfoId,
                n.EmployeeDriverid,
                n.Actualprice,
                ReceivedPrice = i.Actualprice
            });

            var r = m.GroupBy(o => new { o.EmployeeDriverid, o.ReceiptInfoId }).Select(x => new
            {
                EmployeeDriverid = x.Key.EmployeeDriverid,
                ReceiptInfoId = x.Key.ReceiptInfoId,
                Actualprice = x.Sum(y => y.Actualprice),
                ReceivedPrice = x.Sum(y => y.ReceivedPrice)
            }).ToList();

            return await userList.Join(_repositoryUser.GetAll().Where(o => o.FactoryinfoId == user.FactoryinfoId), i => i.UserId, k => k.Id, (i, k) => new
            {
                Name = k.Name,
                Mobile = k.Mobile,
                Id = k.Id,

            }).GroupJoin(_repositorySettlementInfo.GetAll().Where(o => o.RestaurantPayStatus == RestaurantPayStatus.已收完款 || o.RestaurantPayStatus == RestaurantPayStatus.部分收款).GroupBy(o => o.EmployeeDriverid).Select(o => new { EmployeeDriverid = o.Key, TaskCount = o.Count() }), i => i.Id, k => k.EmployeeDriverid,
                 (i, k) => new
                 {
                     Name = i.Name,
                     Mobile = i.Mobile,
                     Id = i.Id,
                     TaskCount = k.Sum(s => s.TaskCount)
                 }).GroupJoin(r.GroupBy(o => o.EmployeeDriverid).Select(o => new { EmployeeDriverid = o.Key, MarkCount = o.Count(), Actualprice = o.Sum(s => s.ReceivedPrice) }), i => i.Id, k => k.EmployeeDriverid,
                 (i, k) => new SettlementInfoPrePaymentInfo
                 {
                     Name = i.Name,
                     Mobile = i.Mobile,
                     UserId = i.Id,
                     TaskCount = i.TaskCount,
                     MarkCount = k.Sum(s => s.MarkCount),
                     Actualprice = k.Sum(s => s.Actualprice)
                 }).Where(o => o.TaskCount != 0 && o.MarkCount != 0).ToPagedListAsync(page, pageSize);
        }


        public async Task<List<SettlementInfoPrePaymentInfo>> GetAllPaymentInfoListAsync(long? id)
        {
            var user = await base.GetCurrentUserAsync();

            var data = _repositorySettlementInfo.GetAll().Where(o => o.FactoryinfoId == user.FactoryinfoId && o.EmployeeDriverid.HasValue == true);
            if (id.HasValue)
                data = data.Where(o => o.EmployeeDriverid == id);

            var userList = data.GroupBy(g => g.EmployeeDriverid).Select(s => new { UserId = s.Key }).ToArray();

            ///得到收据的收款信息同时查看没有缴款的收据
            var m = _repositoryReceiptInfoBySettlementModel.GetAll().Where(o => o.ToVoidStatus != ToVoidStatus.已作废).Join(_repositoryReceiptInfo.GetAll().Where(o => o.PaymentState == PaymentState.未缴款), i => i.ReceiptInfoId, n => n.Id, (i, n) => new
            {
                i.SettlementId,
                Actualprice = i.TaskBackAmount + i.PreferentialAmount + i.UsePrePayment
            }).Join(_repositorySettlementInfo.GetAll(), i => i.SettlementId, n => n.Id, (i, n) => new
            {
                n.ReceiptInfoId,
                n.EmployeeDriverid,
                n.Actualprice,
                ReceivedPrice = i.Actualprice
            });

            var r = m.GroupBy(o => new { o.EmployeeDriverid, o.ReceiptInfoId }).Select(x => new
            {
                EmployeeDriverid = x.Key.EmployeeDriverid,
                ReceiptInfoId = x.Key.ReceiptInfoId,
                Actualprice = x.Sum(y => y.Actualprice),
                ReceivedPrice = x.Sum(y => y.ReceivedPrice)
            }).ToList();

            return await userList.Join(_repositoryUser.GetAll().Where(o => o.FactoryinfoId == user.FactoryinfoId), i => i.UserId, k => k.Id, (i, k) => new
            {
                Name = k.Name,
                Mobile = k.Mobile,
                Id = k.Id,

            }).GroupJoin(_repositorySettlementInfo.GetAll().Where(o => o.RestaurantPayStatus == RestaurantPayStatus.已收完款 || o.RestaurantPayStatus == RestaurantPayStatus.部分收款).GroupBy(o => o.EmployeeDriverid).Select(o => new { EmployeeDriverid = o.Key, TaskCount = o.Count() }), i => i.Id, k => k.EmployeeDriverid,
                 (i, k) => new
                 {
                     Name = i.Name,
                     Mobile = i.Mobile,
                     Id = i.Id,
                     TaskCount = k.Sum(s => s.TaskCount)
                 }).GroupJoin(r.GroupBy(o => o.EmployeeDriverid).Select(o => new { EmployeeDriverid = o.Key, MarkCount = o.Count(), Actualprice = o.Sum(s => s.ReceivedPrice) }), i => i.Id, k => k.EmployeeDriverid,
                 (i, k) => new SettlementInfoPrePaymentInfo
                 {
                     Name = i.Name,
                     Mobile = i.Mobile,
                     UserId = i.Id,
                     TaskCount = i.TaskCount,
                     MarkCount = k.Sum(s => s.MarkCount),
                     Actualprice = k.Sum(s => s.Actualprice)
                 }).Where(o => o.TaskCount != 0 && o.MarkCount != 0).ToListAsync();

        }
        #endregion



        public async Task<SettlementReceivableDto> GetBySettlementIdAsync(Guid SettlementId)
        {
            var usermodel = await _userAppService.GetByIdUserAsync(AbpSession.UserId.Value);
            string sql = $@"select a.Id as SettlementId,a.ExamineStatus,a.CreationTime,CreationNumber,d.Id as DriverId,Name as DriverName,RestaurantName,a.TotalPrice,Discountprice,Actualprice 
                            from SettlementInfo a,RestaurantInfo b,AbpUsers d where a.Restaurantid = b.id  and b.EmployeeDriverid=d.Id and b.FactoryinfoId='{usermodel.FactoryinfoId}' and a.Id='{SettlementId}'";

            var model = _sqlExecuter.FromDapperSqlQuery<SettlementReceivableDto>(sql, null).FirstOrDefault();

            return _map.Map<SettlementReceivableDto>(model);
        }
        /// <summary>
        /// 修改结账信息
        /// </summary>
        /// <returns>The update.</returns>
        /// <param name="id">Identifier.</param>
        /// <param name="input">Input.</param>
        public async Task Update(Guid id, SettlementInfoInput input)
        {
            var model = await _repositorySettlementInfo.GetAsync(id);
            model = _map.Map(input, model);
            await _repositorySettlementInfo.UpdateAsync(model);

        }

        #region 财务修改审核状态
        /// <summary>
        /// App 能否看到自己的收款情况
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task UpdateStatus(Guid id)
        {
            var model = await _repositorySettlementInfo.GetAsync(id);
            model.ExamineStatus = Core.SettlementInfoModel.ExamineStatus.已审核;
            await _settlementInfoManager.UpdateSettlement(model);
        }
        #endregion
        #region App修改配送金额
        public async Task UpdateDiscountprice(Guid id, decimal discountprice)
        {
            var model = await _repositorySettlementInfo.GetAsync(id);
            model.Discountprice = discountprice;
            model.Actualprice = model.Totalprice - discountprice;
            model.ExamineStatus = Core.SettlementInfoModel.ExamineStatus.已审核;
            await _settlementInfoManager.UpdateSettlement(model);
        }
        #endregion
        #region 修改收据收款确认状态
        [Obsolete]
        public async Task EditRestaurantPayStatus(List<Guid> id)
        {
            var model = _repositorySettlementInfo.GetAll().Where(o => id.Any(t => t == o.Id));
            foreach (var item in model)
            {
                item.RestaurantPayStatus = RestaurantPayStatus.已收完款;
                await _settlementInfoManager.UpdateSettlement(item);
            }
        }
        #endregion
        public async Task ModifyAsync(ModifyReceiptDto input)
        {
            //删除
            //if (!string.IsNullOrEmpty(input.deleteIds))
            //{
            //    foreach (var item in input.deleteIds.Split(','))
            //    {
            //        await _repositorySettlementInfo.DeleteAsync(new Guid(item));
            //    }
            //}
            var user = await base.GetCurrentUserAsync();
            if (input.MakingReceipts != null && input.beginTime.HasValue && input.endTime.HasValue)
            {

                foreach (var item in input.MakingReceipts)
                {
                    //var typeNumberIdByPrice = item.TypeNumber.GroupBy(g => new { g.TypeNumberId }).Count();

                    //if (typeNumberIdByPrice < item.TypeNumber.Count())//有相同型号
                    //{
                    //    //根据型号与金额分组
                    //    var t2 = item.TypeNumber.GroupBy(g => new { g.TypeNumberId, g.TypeNumberPrice }).Count();

                    //    if (typeNumberIdByPrice != t2)//判断是否有不同单价
                    //        throw new UserFriendlyException(2, $"同一个餐厅出现配送型号出现多个不同单价");
                    //}


                    //var entity = _repositorySettlementInfo.GetAll().Where(o => o.Id == item.ReceiptId).FirstOrDefault();
                    SettlementInfo entity = new SettlementInfo()
                    {
                        Id = _guid.Create(),
                        FactoryinfoId = user.FactoryinfoId,
                        Restaurantid = item.Restaurantid,
                        Totalprice = item.Sum + item.DiscountedPrice,
                        Discountprice = item.DiscountedPrice,
                        Actualprice = item.Sum,
                        DeliveryDate = input.beginTime.Value.ToString("yyyy-MM-dd") + " 至 " + input.endTime.Value.ToString("yyyy-MM-dd"),
                        BeginTime = input.beginTime,
                        EndTime = input.endTime,
                        RemarksConten = item.Remarks,
                        ExamineStatus = Core.SettlementInfoModel.ExamineStatus.已审核
                    };

                    Dictionary<Guid, SeltmentTypeNumberDto> sListGuid = new Dictionary<Guid, SeltmentTypeNumberDto>();

                    //修改所有关联的配送详情的结账状态
                    var modellist = _repositoryDistributionInfo.GetAll().Where(o => o.SettlementId.HasValue == false && o.Restaurantid == item.Restaurantid && o.CreationTime >= input.beginTime && o.CreationTime <= input.endTime.Value.AddHours(24));
                    SeltmentTypeNumberDto m = new SeltmentTypeNumberDto();
                    m.DisId = modellist.Select(o => o.Id).ToList();
                    m.TypeNumber = item.TypeNumber;
                    sListGuid.Add(entity.Id, m);

                    await _repositorySettlementInfo.InsertAndGetIdAsync(entity).ContinueWith((obj) =>
                    {
                        Task.Factory.StartNew(() =>
                        {
                            var c = obj.Result;
                            var eventDate = new RemoteEventData(RemoteTypeHelp.TypeSettlementInfo)
                            {
                                Data = { [RemoteTypeHelp.ListT] = sListGuid }
                            };
                            remoteEventBus.Publish(RemoteTypeHelp.TopicSettlementInfo, eventDate);

                        });
                    });

                    #region 20181009
                    //if (entity != null)
                    //{
                    //entity.Discountprice = item.DiscountedPrice;
                    //entity.Totalprice = item.Sum + item.DiscountedPrice;
                    //entity.Actualprice = item.Sum;
                    //entity.RemarksConten = item.Remarks;

                    //if (item.TypeNumber.Count > 0)
                    //{
                    //    foreach (var i in item.TypeNumber)
                    //    {
                    //        var details = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.TypeNumberInfoModel).Where(o => o.PricesId == item.ReceiptId && o.TypeNumberInfoId == i.TypeNumberId);

                    //        foreach (var j in details)
                    //        {
                    //            ///重新结算确认订单单价
                    //            j.TypeNumberPrice = i.TypeNumberPrice / j.TypeNumberInfoModel.Count;
                    //            j.Sumprice = j.TypeNumberPrice * ((j.Distributioncount - j.Backboxcount) * j.TypeNumberInfoModel.Count - j.Backnumbercount - j.Damagecount);
                    //            //修改当前配送值
                    //            var m = _repositoryDistributionInfo.GetAllIncluding(o => o.DistributionInfoListDetails).Where(o => o.Id == j.DistributionInfoId).FirstOrDefault();
                    //            if (m != null)
                    //            {
                    //                var price = m.DistributionInfoListDetails.Where(o => o.Id != j.Id).Sum(o => o.Sumprice);
                    //                m.TotalPrice = price + j.Sumprice;
                    //                await _repositoryDistributionInfo.UpdateAsync(m);
                    //            }
                    //            await _repositoryDistributionInfoDetails.UpdateAsync(j);

                    //        }

                    //    }

                    //}
                    //}
                    #endregion
                }

            }

        }

        /// <summary>
        /// 后台-获取分配单据信息
        /// </summary>
        /// <param name="pageIdx"></param>
        /// <param name="pageSize"></param>
        /// <param name="keywords"></param>
        /// <returns></returns>
        public async Task<IPagedList<SettlementInfoDto>> GetAssignReceiptListAsync(int pageIdx, int pageSize, long? DriverId, Guid? Line, DateTime? beginTime, DateTime? endTime, BalanceCycleEnum? BalanceCycleEnum, RestaurantPayStatus? RestaurantPayStatus, string AssignmentStatus, string keywords)
        {
            var user = await base.GetCurrentUserAsync();
            var query = _repositorySettlementInfo.GetAllIncluding(o => o.RestaurantInfoModel, o => o.EmployeeDriverDao).Where(o => o.FactoryinfoId == user.FactoryinfoId && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核 && o.BalanceWayEnum == BalanceWayEnum.定期结算 && o.RestaurantPayStatus != Core.SettlementInfoModel.RestaurantPayStatus.作废);

            if (DriverId.HasValue)
                query = query.Where(o => o.EmployeeDriverid == DriverId.Value);

            if (Line.HasValue && Line != Guid.Empty)
            {
                var lineUsers = _repositoryLoadDriverLine.GetAll().Where(o => o.LineId == Line.Value).Select(o => o.DriverId);
                query = query.Where(o => lineUsers.Any(s => s == o.EmployeeDriverid));
            }

            //配送开始时间
            if (beginTime.HasValue)
                query = query.Where(o => o.BeginTime.HasValue && o.BeginTime >= beginTime.Value);
            //配送结束时间
            if (endTime.HasValue)
                query = query.Where(o => o.EndTime.HasValue && o.EndTime <= endTime.Value.AddHours(24));

            //结算类型
            if (BalanceCycleEnum.HasValue)
                query = query.Where(o => o.RestaurantInfoModel.BalanceCycle == BalanceCycleEnum.Value);

            //缴款状态
            if (RestaurantPayStatus.HasValue)
                query = query.Where(o => o.RestaurantPayStatus == RestaurantPayStatus.Value);

            //分配状态
            if (!string.IsNullOrEmpty(AssignmentStatus))
            {
                if (AssignmentStatus == "已分配")
                {
                    query = query.Where(o => o.EmployeeDriverid.HasValue);
                }
                else if (AssignmentStatus == "未分配")
                {
                    query = query.Where(o => o.EmployeeDriverid == null);
                }
            }

            if (!string.IsNullOrEmpty(keywords))
                query = query.Where(o => o.RestaurantInfoModel.RestaurantName.Contains(keywords));

            return await query.OrderByDescending(m => m.CreationTime).ProjectTo<SettlementInfoDto>().ToPagedListAsync(pageIdx, pageSize);
        }

        public async Task<List<SettlementExportDto>> GetExportAssignReceiptListAsync(long? DriverId, Guid? Line, DateTime? beginTime, DateTime? endTime, BalanceCycleEnum? BalanceCycleEnum, RestaurantPayStatus? RestaurantPayStatus, string AssignmentStatus, string keywords)
        {
            var user = await base.GetCurrentUserAsync();
            var query = _repositorySettlementInfo.GetAll().Where(o => o.FactoryinfoId == user.FactoryinfoId && o.ExamineStatus == Core.SettlementInfoModel.ExamineStatus.已审核 && o.BalanceWayEnum == BalanceWayEnum.定期结算).Join(_repositoryRestaurantInfo.GetAll(), a => a.Restaurantid, b => b.Id, (a, b) => new
            {
                a.EmployeeDriverid,
                a.RestaurantPayStatus,
                a.CreationTime,
                a.BeginTime,
                a.EndTime,
                a.CreationNumber,
                b.RestaurantName,
                b.BalanceCycle,
                a.DeliveryDate,
                a.Totalprice,
                a.Discountprice,
                a.Actualprice
            }).Join(_repositoryUser.GetAll(), a => a.EmployeeDriverid, b => b.Id, (a, b) => new SettlementExportDto
            {
                EmployeeDriverid = a.EmployeeDriverid,
                EmployeeName = b.Name,
                RestaurantPayStatus = a.RestaurantPayStatus,
                CreationTime = a.CreationTime,
                CreationNumber = a.CreationNumber,
                RestaurantName = a.RestaurantName,
                BalanceCycle = a.BalanceCycle,
                DeliveryDate = a.DeliveryDate,
                BeginTime = a.BeginTime.Value,
                EndTime = a.EndTime.Value,
                TotalPrice = a.Totalprice,
                Discountprice = a.Discountprice,
                Actualprice = a.Actualprice
            });

            if (DriverId.HasValue)
                query = query.Where(o => o.EmployeeDriverid == DriverId.Value);

            if (Line.HasValue && Line != Guid.Empty)
            {
                var lineUsers = _repositoryLoadDriverLine.GetAll().Where(o => o.LineId == Line.Value).Select(o => o.DriverId);
                query = query.Where(o => lineUsers.Any(s => s == o.EmployeeDriverid));
            }

            //配送开始时间
            if (beginTime.HasValue)
                query = query.Where(o => o.BeginTime >= beginTime.Value);
            //配送结束时间
            if (endTime.HasValue)
                query = query.Where(o => o.EndTime <= endTime.Value.AddHours(24));

            //结算类型
            if (BalanceCycleEnum.HasValue)
                query = query.Where(o => o.BalanceCycle == BalanceCycleEnum.Value);

            //缴款状态
            if (RestaurantPayStatus.HasValue)
                query = query.Where(o => o.RestaurantPayStatus == RestaurantPayStatus.Value);

            //分配状态
            if (!string.IsNullOrEmpty(AssignmentStatus))
            {
                if (AssignmentStatus == "已分配")
                {
                    query = query.Where(o => o.EmployeeDriverid.HasValue);
                }
                else if (AssignmentStatus == "未分配")
                {
                    query = query.Where(o => o.EmployeeDriverid == null);
                }
            }

            if (!string.IsNullOrEmpty(keywords))
                query = query.Where(o => o.RestaurantName.Contains(keywords));

            return await query.OrderByDescending(m => m.CreationTime).ToListAsync();
        }

        #region 后台分配给司机的收据
        /// <summary>
        /// 后台分配给司机的收据
        /// </summary>
        /// <param name="Ids"></param>
        /// <param name="Cashier"></param>
        /// <returns></returns>

        public async Task AssignReceiptAsync(string Ids, long Cashier)
        {
            var ids = Ids.Split('|');

            foreach (var item in ids)
            {
                var entity = _repositorySettlementInfo.GetAll().Where(o => o.Id == new Guid(item)).FirstOrDefault();
                if (entity != null && (entity.RestaurantPayStatus != RestaurantPayStatus.作废 || entity.RestaurantPayStatus != RestaurantPayStatus.坏账确认))
                    entity.EmployeeDriverid = Cashier;
                await _repositorySettlementInfo.UpdateAsync(entity);
                ///分配司机
            }

            _backgroundJobManager.Enqueue<SettlementPayBackGround, BasArg>(new BasArg
            {
                UserId = Cashier
            }, BackgroundJobPriority.Normal, TimeSpan.FromSeconds(5));

        }
        #endregion
        public async Task<List<MakingReceiptOutputDto>> GetSettlementListAsync(string Ids)
        {
            List<Guid> id = new List<Guid>();
            List<MakingReceiptOutputDto> data = new List<MakingReceiptOutputDto>();
            foreach (var item in Ids.Split('|'))
                id.Add(new Guid(item));

            var query = _repositorySettlementInfo.GetAll().Where(o => id.Any(s => s == o.Id)).GroupJoin(_repositoryDistributionInfoDetails.GetAllIncluding(o => o.TypeNumberInfoModel), i => i.Id, j => j.PricesId, (i, j) => new
            {
                Id = i.Id,
                i.Restaurantid,
                CreationNumber = i.CreationNumber,
                DeliveryDate = i.DeliveryDate,
                Sum = i.Totalprice,
                Capital = CapitalHelper.CmycurD(i.Totalprice),
                DiscountedPrice = i.Discountprice + i.ReceivedDiscount,
                RemarksConten = i.RemarksConten,
                Suits = j.GroupBy(o => new { o.TypeNumberInfoId, o.TypeNumberName, o.TypeNumberPrice }).Select(o => new SuitDto
                {
                    Name = o.Key.TypeNumberName,
                    Quantity = o.Sum(s => (s.Distributioncount - s.Backnumbercount - decimal.Round((s.Damagecount + s.Backnumbercount) / s.TypeNumberInfoModel.Count, 2))),
                    Count = o.Sum(s => (s.Distributioncount - s.Backboxcount) * s.TypeNumberInfoModel.Count - s.Damagecount - s.Backnumbercount),
                    Price = o.Key.TypeNumberPrice,
                    Total = o.Sum(s => s.Sumprice)
                }).ToList()
            }).Join(_repositoryRestaurantInfo.GetAll(), i => i.Restaurantid, j => j.Id, (i, j) => new MakingReceiptOutputDto
            {
                Id = i.Id,
                CreationNumber = i.CreationNumber,
                DeliveryDate = i.DeliveryDate,
                Sum = i.Sum,
                Capital = i.Capital,
                DiscountedPrice = i.DiscountedPrice,
                RemarksConten = i.RemarksConten,
                Suits = i.Suits,
                RestaurantName = j.RestaurantName
            });

            return await query.ToListAsync();
        }

        public async Task BatchReview(string ids)
        {

            foreach (var item in ids.Split('|'))
            {
                var entity = _repositorySettlementInfo.GetAll().Where(o => o.Id == new Guid(item)).FirstOrDefault();
                if (entity != null)
                {
                    if (entity.ExamineStatus != Core.SettlementInfoModel.ExamineStatus.已审核)
                    {
                        entity.ExamineStatus = Core.SettlementInfoModel.ExamineStatus.已审核;
                        await _repositorySettlementInfo.UpdateAsync(entity);
                    }
                }
            }
        }


        private Task<List<SettlementInfo>> GetCache
        {
            get
            {
                ICache cache = _catchmanager.GetCache(nameof(SettlementInfo));
                return cache.GetAsync("list", async () => await _repositorySettlementInfo.GetAllIncluding(m => m.RestaurantInfoModel, m => m.EmployeeDriverDao).ToListAsync());
            }

        }
    }
}
